/**
 * FileName: ProductServiceImpl
 * Author: Wb
 * Date: 2025/9/24 10:34
 * Description:
 * History:
 */
package org.test.device.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import io.micrometer.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.test.device.constant.AttributesValue;
import org.test.device.constant.ProductStatusEnum;
import org.test.device.enty.Product;
import org.test.device.enty.ProductProperty;
import org.test.device.enty.ProductType;
import org.test.device.mapper.ProductMapper;
import org.test.device.mapper.ProductPropertyMapper;
import org.test.device.mapper.ProductTypeMapper;
import org.test.device.params.QueryProductParam;
import org.test.device.params.SaveProductParam;
import org.test.device.service.ProductService;
import org.test.device.utils.ResultData;
import org.test.device.utils.SqlTypeConverter;
import org.test.device.architecture.exception.BusinessException;
import org.test.device.vo.product.ProductVoList;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 〈一句话功能简述〉<br>
 * 〈〉
 *
 * @author Wb
 * @create 2025/9/24
 * @since 1.0.0
 */
@Slf4j
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    ProductMapper productMapper;

    @Autowired
    ProductPropertyMapper productPropertyMapper;

    @Autowired
    ProductTypeMapper productTypeMapper;

    /**
     * @param param 查询条件
     * @Author Mr.Wang
     * @Description 获取产品列表
     * @Date 09:54 2025/9/28
     **/
    @Override
    public List<ProductVoList> getProductList(QueryProductParam param) {
        LambdaQueryWrapper<Product> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(Product::getDeleted,0);
        Optional.ofNullable(param.getType())
                .filter(Objects::nonNull)
                .ifPresent(t -> productWrapper.eq(Product::getTypeId, t));

        Optional.ofNullable(param.getSearchKey())
                .filter(key -> !key.isEmpty())
                .ifPresent(k -> productWrapper.and(wrapper -> wrapper
                        .like(Product::getCode, k)
                        .or()
                        .like(Product::getName, k)
                        .or()
                        .like(Product::getAuthMethod, k)
                        .or()
                        .like(Product::getAccessMethod, k)));

        return productMapper.selectList(productWrapper).stream()
                .map(list -> {
                    ProductVoList vo = new ProductVoList();
                    SqlTypeConverter.convertEntity(list, vo, "yyyy-mm-dd HH:mm:ss");
                    //转换类性展示
                    ProductType productType = productTypeMapper.selectById(vo.getTypeId());
                    vo.setTypeName(productType.getCnName());
                    vo.setStatus(ProductStatusEnum.getDescByCode(list.getStatus()));
                    return vo;
                })
                .peek(vo -> log.info("转换后的产品: {}", JSON.toJSONString(vo)))
                .collect(Collectors.toList());
    }

    /**
    * @Author Mr.Wang
    * @Description 选择产品列表
    * @Date 14:44 2025/9/28
    * @param
    **/
    @Override
    public List<Map<String, Object>> getProductChoiceList() {
       List<Map<String,Object>> productChoiceList = productMapper.getProductChoiceList();
        for (Map<String, Object> map : productChoiceList) {
            List<Map<String,Object>> ppList=productPropertyMapper.getProductPropertyChoiceList(Integer.valueOf(map.get("id").toString()));
            map.put("ProductPropertyList",ppList);
        }
        return productChoiceList;
    }


    /**
     * @Author Wb
     * @Description 新增产品信息
     * @Date 15:42 2025/9/25
     * @Param [param]
     * @Return void
     */
    @Override
    public void saveProduct(SaveProductParam param) {
        Product product = new Product();
        SqlTypeConverter.copyEntity(param, product);
        productMapper.insert(product);
        log.info("商品写入成功！:{}", JSON.toJSONString(product));
        List<ProductProperty> parmaList = param.getProperties();
        parmaList.stream().forEach(pp -> {
            pp.setProductId(product.getId());
        });
        productPropertyMapper.insert(parmaList);
        log.info("商品的物模型属性写入成功！:{}", JSON.toJSONString(parmaList));
    }

    /**
     * @param code 产品code
     * @Author Mr.Wang
     * @Description 启用产品
     * @Date 09:53 2025/9/28
     **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public ResultData updateProductStatus(String code,Integer status) {
        // 检查参数有效性
        if (StringUtils.isEmpty(code)) {
            return new ResultData("产品编码不能为空！");
        }
        try {
            Product product = productMapper.selectOne(new LambdaQueryWrapper<Product>()
                    .eq(Product::getCode, code)
                    .select(Product::getId, Product::getStatus));
            if (product == null) {
                return new ResultData("未找到编码为：" + code + " 的产品！");
            }
            LambdaUpdateWrapper<Product> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Product::getCode, code);
            product.setStatus(status);
            productMapper.update(product,updateWrapper);
        } catch (Exception e) {
            log.error("更新产品状态异常，产品编码：{}", code, e);
            throw new BusinessException("修改失败：{}", e);
        }
        return new ResultData("修改成功！");
    }

    /**
    * @Author Mr.Wang
    * @Description 修改产品信息
    * @Date 11:07 2025/9/28
    * @param code 产品编码
    * @param param 修改数据
    **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public ResultData updateProduct(String code, SaveProductParam param) {
        // 检查参数有效性
        if (StringUtils.isEmpty(code)) {
            return new ResultData("产品编码不能为空！");
        }
        try {
            Product product = productMapper.selectOne(new LambdaQueryWrapper<Product>()
                    .eq(Product::getCode, code)
                    .select(Product::getId, Product::getStatus));
            if (product == null) {
                return new ResultData("未找到编码为：" + code + " 的产品！");
            }
            List<ProductProperty> newAddList=new ArrayList<>();
            SqlTypeConverter.copyEntity(param,product);
            LambdaUpdateWrapper<Product> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Product::getCode, code);
            productMapper.update(product,updateWrapper);
            log.info("开始修改产品物模型:{}",JSON.toJSONString(param.getProperties()));
            List<ProductProperty> propertyList = param.getProperties().stream()
                    .map(property -> {
                        if (property.getProductId() == 0) {
                            property.setProductId(product.getId());
                            newAddList.add(property);
                        }
                        return property;
                    }).toList();
            productPropertyMapper.insertOrUpdate(propertyList);
            log.info("新增的物模型属性:{}",JSON.toJSONString(newAddList));
        } catch (Exception e) {
            log.error("更新产品状态异常，产品编码：{}", code, e);
            // 抛出异常触发事务回滚
            throw new BusinessException("修改失败：{}", e);
        }
        return new ResultData("修改成功！");
    }

    /**
    * @Author Mr.Wang
    * @Description 删除产品信息
    * @Date 13:56 2025/9/28
    * @param code
    **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public ResultData deletedProduct(String code) {
        // 检查参数有效性
        if (StringUtils.isEmpty(code)) {
            return new ResultData("产品编码不能为空！");
        }
        try {
            Product product = productMapper.selectOne(new LambdaQueryWrapper<Product>()
                    .eq(Product::getCode, code)
                    .select(Product::getId, Product::getStatus));
            if (product == null) {
                return new ResultData("未找到编码为：" + code + " 的产品！");
            }
            product.setDeleted(AttributesValue.DELETED.getCode());
            productMapper.updateById(product);
            log.info("删除产品成功！code:{}",code);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("删除产品失败:{}",code,e);
            throw new BusinessException("删除失败！",e);
        }
        return new ResultData("删除成功！");
    }
}